home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
WINMX Assorted Textfiles
/
Ebooks.tar
/
Text - Tech - Electronics - Schematics - DS1820 - Thermometer and Thermostat (HTML TXT).zip
/
D1820.BS2
next >
Wrap
Text File
|
1996-03-12
|
12KB
|
412 lines
' Dallas 1820 Thermometer Demo Program for the STAMP II
' Dan Clemmensen, 20 Jan 96
' hhtp://www.shirenet.com/~dgc
' dgc@shirenet.com
' (703) 759-2686
'
' This demo program reads inputs from multiple Dallas 1820 thermometers
' and displays the temperatures. It permits the user to add and remove
' thermometers, set software thermostat limits, and control output
' pins based on the thermostat limits.
'
' Hardware:
' STAMP II, LCD serial backpack, four buttons, and a one-wire
' interface circuit.
'
' The one-wire interface circuit consists of three cheap IC's and
' is described in detail at the above web site. The circuit is
' connected to the STAMP by two pins, one for input and one for output.
' The circuit also connects to a multidropped string of Dallas 1820
' thermometer IC's. The circuit and software do not permit "parasite
' power" operation of the 1820's, but the use of an additonal pin and
' slight modification to the hardware and software would allow "parasite
' power" operation.
'
' The program consists of the bit-level and byte-level utilities
' for the thermometer and routines to issue the "read temp" and
' "read rom" sequence for a particular thermometer and retrieve
' the results.
'
' A main loop reads the buttons to interpret user commands, and
' calls the command handlers.
'
' Button 1 is a "change mode" command.
' Modes 0-n are to control thermometers 0 thru n.
' Mode n+1 is "add thermometer".
' Mode n+1 is "run" mode,
' Control modes (one per thermometer): button 2 cycles thru the control
' submodes. change therm id, delete, inc temp, dec temp, inc range,
' dec range, change relay.
' When in a submode, button 3 is the execute.
'
' RUN mode: continuously get temperatures from all thermometers, and
' display them
'
' Output messages are sent to the LCD BACKPACK using the SEROUT command
' as in the LCD documentation.
'------------------------------------------
' Variable and Constant declaration section
'------------------------------------------
' --- I/O value aliases. The four buttons are readable via
' the preassigned variables in8, in9, in10, and in11, or collectively
' via the nibble variable named 'inc'.
button4val VAR in8
button3val VAR in9
button2val VAR in10
button1val VAR in11
buttonvals VAR inc
button1mask CON $8
button2mask CON $4
button3mask CON $2
pbuttonvals VAR nib ' prior value of buttons
'
' -- Constants and variables associated with the LCD backpack.
'
'
lcdpin CON 4
N2400 CON 396+$4000 'param for SEROUT: 2400, 8-bit, no parity,invert
lcdinst CON 254
lcdclr CON 1
'
' -- Constants and variables associated with the one-wire interface
' circuit and bit-level protocol
'
stamp_pulse CON 2 'pulsout has a 2 us granularity
thermoutpin CON 7
thermin VAR in6
thermresetlen CON 600/stamp_pulse
thermwr0len CON 60/stamp_pulse
thermwr1len CON 1 'should be 1us, but 2 will work
'
' -- Constants and variables associated with the byte-level
' protocol
'
bytecnt VAR nib
work VAR byte
tbyte VAR byte
crcbyte VAR byte
crcbit VAR bit
'
' Buffer for storage of the responses from the thermometers
' The buffer is 10 bytes. It is defined for both byte and word
' usage.
'
tempbuffw VAR word(5)
tempbuff VAR tempbuffw.byte0
'
' variables and constants associated with program control
'
mode VAR byte 'current operating mode.
submode VAR nib 'current submode
max_submode CON 7
'
' -- Constants, variables, and data associated with the ID array.
' The array is maintained in the DATA area of the STAMP EEPROM. There is
' an entry for each thermometer. Each entry is 11 bytes long, and contains
' the 8-byte ROM id and three thermostat parameters: the temperature, the
' range, and the relay mask. Note that the data is not initialized by this
' source file. Instead, the user uses the "Change" command to add thermometers
' and thermostat settings.
' Since the STAMP download preserves uninitialized data, this program may be
' modified and reloaded into the STAMP without affecting the IDs that were
' stored earlier, as long as no additional DATA is declared.
'
idcnt VAR byte
id_max VAR byte
id_entry_len CON 11
temp_offset CON 8
range_offset CON 9
relay_offset CON 10
nbr_of_ids DATA (1) 'highest device num
idarray DATA (11) 'first ID
'
'------------------------------------------------
' Main Program.
'------------------------------------------------
'
'initialization
' set the output pin to output a 1 as the default. This causes the PULSOUT
' commands to send negative-going pulses. Move the number of thermometers
' into working storage
'
HIGH thermoutpin
READ nbr_of_ids,id_max
mode=id_max+1
'
' Main loop. This is an endless loop that samples the buttons for a
' command. When a command is read, it is executed. If no command is detected,
' the program executes the display for the current mode.
'
main_loop:
IF buttonvals=pbuttonvals THEN nochange
GOSUB buttonchange
nochange:
IF mode=id_max+1 THEN call_temp
GOSUB therm_mode
GOTO main_loop
call_temp:
GOSUB temp_display
GOTO main_loop
'
'------------------------------------------------
' Process one of the thermometer modes.
'------------------------------------------------
'
therm_mode:
GOSUB rom_display
RETURN
'
'------------------------------------------------
' Subroutine to check for button input and change the mode
' accordingly.
'------------------------------------------------
'
buttonchange:
depress VAR work
depress=(pbuttonvals) & (~buttonvals)
pbuttonvals=buttonvals
IF depress&button1mask THEN modechange
IF depress&button2mask THEN submodechange
IF depress&button3mask THEN execute
RETURN
modechange:
mode=(mode+1)//(id_max+2)
submode=0
RETURN
submodechange:
IF mode>id_max THEN no_submode
submode=(submode+1)//max_submode
no_submode:
RETURN
execute:
BRANCH submode,[change_id, delete_id, inc_temp, dec_temp, inc_range,dec_range, change_relay]
RETURN
change_id:
GOSUB romread
IF crcbyte<>0 THEN no_change
FOR bytecnt=0 TO 7
WRITE idarray+(id_entry_len*idcnt)+bytecnt,tempbuff(bytecnt)
NEXT
IF mode<id_max THEN no_change
id_max=id_max+1
WRITE nbr_of_ids,id_max
no_change:
RETURN
delete_id:
WRITE idarray+(id_entry_len*idcnt),0
RETURN
inc_temp:
READ idarray+(id_entry_len*idcnt)+temp_offset,work
work=work+1
write idarray+(id_entry_len*idcnt)+temp_offset,work
RETURN
dec_temp:
READ idarray+(id_entry_len*idcnt)+temp_offset,work
work=work-1
write idarray+(id_entry_len*idcnt)+temp_offset,work
RETURN
inc_range:
READ idarray+(id_entry_len*idcnt)+range_offset,work
work=work+1
write idarray+(id_entry_len*idcnt)+range_offset,work
RETURN
dec_range:
READ idarray+(id_entry_len*idcnt)+range_offset,work
work=work-1
write idarray+(id_entry_len*idcnt)+range_offset,work
RETURN
change_relay:
RETURN
'
'------------------------------------------------
' Subroutine to read the temperature of
' each thermometer in the list, compute the faranheit temp, and display
' the result.
'------------------------------------------------
'
temp_display:
GOSUB tempcvt
FOR idcnt= 0 TO id_max
GOSUB tempread
DEBUG "T",dec idcnt,":"
GOSUB faren
DEBUG dec tempbuffw(2)/100+32,".", dec2 tempbuffw(2)//100
' FOR work=0 TO 8
' DEBUG hex tempbuff(work)," "
' NEXT
DEBUG CR
NEXT
RETURN
'
'------------------------------------------------
'Subroutine to read the rom-id of a single 1820 and display it.
'------------------------------------------------
'
rom_display:
GOSUB romread
FOR work=0 TO 7
DEBUG hex tempbuff(work)," "
NEXT
DEBUG CR
RETURN
'
'------------------------------------------------
' romread
' issue a romread command and read the response
'------------------------------------------------
'
romread:
GOSUB treset
tbyte=$33
GOSUB twrbyte
crcbyte=0
FOR bytecnt=0 TO 7
GOSUB trdbyte
tempbuff(bytecnt)=tbyte
NEXT
IF crcbyte=0 THEN romread_ok
DEBUG "BAD CRC!", CR
romread_ok:
RETURN
'
'------------------------------------------------
' tempcvt. Issue a convert command to all of the
' 1820's at once.
'------------------------------------------------
'
tempcvt:
GOSUB treset
tbyte=$CC 'skip ROM (i.e., address the command to all devices)
GOSUB twrbyte
tbyte=$44 ' convert (i.e., sense and store the temperature)
GOSUB twrbyte
PAUSE 500 ' conversion can take up to .5 sec.
RETURN
'
'------------------------------------------------
' tempread. read the temperature data from a particular
' 1820
'------------------------------------------------
'
tempread:
GOSUB treset
GOSUB sendid
tbyte=$BE
GOSUB twrbyte
crcbyte=0
FOR bytecnt=0 TO 8
GOSUB trdbyte
tempbuff(bytecnt)=tbyte
NEXT
IF crcbyte=0 THEN crc_ok
DEBUG "bad CRC!",CR
crc_ok:
RETURN
'
'------------------------------------------------
'sendid. send the ID string of the device number given in idcnt
'------------------------------------------------
'
sendid:
tbyte=$55
GOSUB twrbyte
FOR bytecnt=0 TO 7
READ idarray+(8*idcnt)+bytecnt,tbyte
GOSUB twrbyte
NEXT
RETURN
'
'------------------------------------------------
'trdbyte. Read 8 bits into tbyte
'------------------------------------------------
'
trdbyte:
FOR work=0 TO 7
GOSUB trdbit
tbyte.bit0(work)=thermin
crcbit=crcbyte.bit0^thermin
crcbyte=(crcbyte>>1)
crcbyte.bit7=crcbit
crcbyte.bit2=crcbyte.bit2^crcbit
crcbyte.bit3=crcbyte.bit3^crcbit
NEXT
RETURN
'
'------------------------------------------------
'twrbyte. write (i.e., send) the 8 bits from tbyte
'------------------------------------------------
'
twrbyte:
FOR work=0 TO 7
IF tbyte.bit0(work)=0 THEN twr0
GOSUB twrbit1
GOTO twrbytenext
twr0:
GOSUB twrbit0
twrbytenext:
NEXT
RETURN
'
'------------------------------------------------
'treset. send a reset pulse. wait one ms for the "presence" responses
' to die down.
'------------------------------------------------
'
treset:
PULSOUT thermoutpin,thermresetlen
PAUSE 1
RETURN
'
'------------------------------------------------
'trdbit. Read one bit. response will be in thermin. Note that
' this routine is simply another name for twrbit1! The only difference
' is in the mind of the programmer.
'------------------------------------------------
'
trdbit:
'
'------------------------------------------------
'twrbit1.
' write (send) a one bit.
'------------------------------------------------
'
twrbit1:
PULSOUT thermoutpin,thermwr1len
RETURN
'
'------------------------------------------------
'twrbit0.
' write (send) zero bit.
'------------------------------------------------
'
twrbit0:
PULSOUT thermoutpin,thermwr0len
RETURN
'
'------------------------------------------------
' faren. This routine converts the thermometer input to
' degrees and tenths "biased" farenheit. (Actually, returns hundredths,
' but the true precision isn't this high.) input is in the
' temp buff. output is to the "reserved word" in the temp buff,
' treated as a 16-bit word named tempbuffw(2).
' The result is biased by 32 degrees farenheit. Add 32 degrees to get
' actual farenheit.
'
' The 1820 returns Centigrade whole degreees, plus
' a max count and remaining count for the current degree.
' The hi-res temp is computed as : hi_res=lo_res+.75-remain/max.
' The result is converted to farenheit by multiplying by 1.8 and
' adding 32.
' This routine uses 16-bit integer arithmetic, we convert to hundredths
' of a farenheit degree first: f_lores_100ths=lo_res*180, then add the .75C:
' +135. Now we have to subtract the correction factor: -180*remain/max.
'------------------------------------------------
'
faren:
tempbuffw(2)=(tempbuffw(0)>>1)*180+135 - (180*tempbuff(6)/tempbuff(7))
RETURN